home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / dev / cross / unhex.lha / unhex.c next >
Encoding:
C/C++ Source or Header  |  1999-08-04  |  6.4 KB  |  303 lines

  1. #include <exec/memory.h>
  2. #include <clib/exec_protos.h>
  3. #include <clib/dos_protos.h>
  4. #include <pragmas/exec_sysbase_pragmas.h>
  5. #include <pragmas/dos_pragmas.h>
  6. #include <dos/dos.h>
  7.  
  8. struct Library *DOSBase, *SysBase;
  9. __far struct FileInfoBlock fib;
  10. struct {
  11.     STRPTR from;
  12.     STRPTR to;
  13.     ULONG *fill;
  14. } arg = { 0 };
  15. #define TEMPLATE "FROM/A,TO/A,FILL/N"
  16. STRPTR inpoint;
  17. ULONG rc;
  18. UBYTE unhex(void);
  19. UBYTE unhexbyte(void);
  20.  
  21. __saveds main()
  22. {
  23.     SysBase = *((struct Library **)4L);
  24.     rc = 20;
  25.     if(DOSBase = OpenLibrary("dos.library",36))
  26.     {
  27.         struct RDArgs *rda;
  28.         Printf("%s © Russian Digital Computing\n",6+"$VER: unhex 1.0 "__AMIGADATE__);
  29.         if(rda = ReadArgs(TEMPLATE,(LONG *)&arg,NULL))
  30.         {
  31.             BPTR infile;
  32.             if(infile = Open(arg.from,MODE_OLDFILE))
  33.             {
  34.                 STRPTR indata;
  35.                 ExamineFH(infile,&fib);
  36.                 if(inpoint = indata = AllocVec(fib.fib_Size+1000,MEMF_CLEAR))
  37.                 {
  38.                     *(indata+fib.fib_Size+998) = 0x0A;
  39.                     if(-1!=Read(infile,indata,fib.fib_Size))
  40.                     {
  41.                         ULONG end = 0, erc = 0, nl = 0, segment = 0;
  42.                         ULONG line = 0, actualen = 0, lastaddr = 0;
  43.                         while(TRUE)
  44.                         {
  45.                             line++;
  46.                             if(':'==*inpoint)
  47.                             {
  48.                                 STRPTR checkpoint = ++inpoint;
  49.                                 UBYTE len = unhex();
  50.                                 UBYTE hiaddr = unhex();
  51.                                 UBYTE loaddr = unhex();
  52.                                 UBYTE type = unhex();
  53.                                 UBYTE sum = len + loaddr + hiaddr + type;
  54.                                 ULONG checklen = (len+5)<<1;
  55.                                 while(checklen--)
  56.                                 {
  57.                                     UBYTE tb = *checkpoint++;
  58.                                     if((tb<'0')||
  59.                                         (tb>'f')||
  60.                                         ((tb>'9')&&(tb<'A'))||
  61.                                         ((tb>'F')&&(tb<'a')))
  62.                                     {
  63.                                         erc = 3;
  64.                                         goto hexend;
  65.                                     }
  66.                                 }
  67.                                 switch(type)
  68.                                 {
  69.                                     case 0: //data
  70.                                     {
  71.                                         ULONG fulladdr = segment + (hiaddr<<8) + loaddr;
  72.                                         if(lastaddr!=fulladdr)
  73.                                         {
  74.                                             nl=1;
  75.                                         }
  76.                                         lastaddr = fulladdr+len;
  77.                                         if(lastaddr>actualen)
  78.                                         {
  79.                                             actualen=lastaddr;
  80.                                         }
  81.                                         while(len--) sum += unhex();
  82.                                         if((UBYTE)(sum+unhex()))
  83.                                         {
  84.                                             erc = 1;
  85.                                             goto hexend;
  86.                                         }
  87.                                         break;
  88.                                     }
  89.                                     case 1: //EOF
  90.                                     {
  91.                                         if(loaddr|hiaddr|len) //it is not a typo
  92.                                         {
  93.                                             erc = 3;
  94.                                             goto hexend;
  95.                                         }
  96.                                         if((UBYTE)(sum+unhex()))
  97.                                         {
  98.                                             erc = 1;
  99.                                         }
  100.                                         end = 1;
  101.                                         goto hexend;
  102.                                     }
  103.                                     case 2: //segment address
  104.                                     case 4: //linear address
  105.                                     {
  106.                                         UBYTE hisegm = unhex();
  107.                                         UBYTE losegm = unhex();
  108.                                         if(loaddr|hiaddr|(len-2))
  109.                                         {
  110.                                             erc = 3;
  111.                                             goto hexend;
  112.                                         }
  113.                                         segment = (hisegm<<12) + (losegm<<4);
  114.                                         if(4==type)
  115.                                         {
  116.                                             segment <<= 12;
  117.                                         }
  118.                                         if((UBYTE)(sum+hisegm+losegm+unhex()))
  119.                                         {
  120.                                             erc = 1;
  121.                                             goto hexend;
  122.                                         }
  123.                                         break;
  124.                                     }
  125.                                     case 3: //segment start address
  126.                                     case 5: //linear start address
  127.                                     {
  128.                                         if(loaddr|hiaddr|(len-4))
  129.                                         {
  130.                                             erc = 3;
  131.                                             goto hexend;
  132.                                         }
  133.                                         while(len--) sum += unhex();
  134.                                         if((UBYTE)(sum+unhex()))
  135.                                         {
  136.                                             erc = 1;
  137.                                             goto hexend;
  138.                                         }
  139.                                         break;
  140.                                     }
  141.                                     default:
  142.                                     {
  143.                                         erc = 2;
  144.                                         goto hexend;
  145.                                     }
  146.                                 }
  147.                             }
  148.                             while((0x0A!=*inpoint)&&(0x0D!=*inpoint))
  149.                             {
  150.                                 inpoint++;
  151.                             }
  152.                             if((0x0D==*inpoint)&&(0x0A==inpoint[1]))
  153.                             {
  154.                                 inpoint++;
  155.                             }
  156.                             if((inpoint++)>(indata+fib.fib_Size))
  157.                             {
  158.                                 break;
  159.                             }
  160.                         }
  161.                         hexend:
  162.                         if(erc)
  163.                         {
  164.                             static STRPTR errtxt[] = {
  165.                                 "Checksum error at",
  166.                                 "Unknown record type at",
  167.                                 "Invalid" };
  168.                             Printf("%s line %ld\n",errtxt[erc-1],line);
  169.                             if(!actualen)
  170.                             {
  171.                                 Printf("Possibly n%s","ot an Intel Hex file\n");
  172.                             }
  173.                         }
  174.                         else
  175.                         {
  176.                             if(actualen)
  177.                             {
  178.                                 if(end)
  179.                                 {
  180.                                     STRPTR outdata = inpoint = indata;
  181.                                     ULONG outmem = 0, segment = 0;
  182.                                     BPTR outfile;
  183.                                     if(nl)
  184.                                     {
  185.                                         Printf("Warning: non-linear file\n");
  186.                                         if(outdata = AllocVec(actualen,MEMF_CLEAR))
  187.                                         {
  188.                                             if(arg.fill)
  189.                                             {
  190.                                                 ULONG count = actualen;
  191.                                                 STRPTR fillpoint = outdata;
  192.                                                 UBYTE filler = *arg.fill;
  193.                                                 while(count--)
  194.                                                 {
  195.                                                     *fillpoint++ = filler;
  196.                                                 }
  197.                                             }
  198.                                             outmem = 1;
  199.                                         }
  200.                                         else
  201.                                         {
  202.                                             Printf("Can't allocate memory for output file\n");
  203.                                         }
  204.                                     }
  205.                                     if(outdata)
  206.                                     {
  207.                                         while(':'==*inpoint++)
  208.                                         {
  209.                                             UBYTE len = unhex();
  210.                                             UBYTE hiaddr = unhex();
  211.                                             UBYTE loaddr = unhex();
  212.                                             UBYTE type = unhex();
  213.                                             switch(type)
  214.                                             {
  215.                                                 case 0:
  216.                                                 {
  217.                                                     STRPTR outpoint = outdata + segment + (hiaddr<<8) + loaddr;
  218.                                                     while(len--) *outpoint++ = unhex();
  219.                                                     break;
  220.                                                 }
  221.                                                 case 2:
  222.                                                 {
  223.                                                     segment = unhex()<<12;
  224.                                                     segment += unhex()<<4;
  225.                                                     break;
  226.                                                 }
  227.                                             }
  228.                                             inpoint += 2;
  229.                                             while('!'>*inpoint) inpoint++;
  230.                                         }
  231.                                         if(outfile = Open(arg.to,MODE_NEWFILE))
  232.                                         {
  233.                                             if(actualen==Write(outfile,outdata,actualen))
  234.                                             {
  235.                                                 Close(outfile);
  236.                                                 Printf("Done!\n");
  237.                                                 rc = 0;
  238.                                             }
  239.                                             else
  240.                                             {
  241.                                                 Printf("Write file error\n");
  242.                                             }
  243.                                         }
  244.                                         else
  245.                                         {
  246.                                             Printf("Can't open outfile\n");
  247.                                         }
  248.                                         if(outmem)
  249.                                         {
  250.                                             FreeVec(outdata);
  251.                                         }
  252.                                     }
  253.                                 }
  254.                                 else
  255.                                 {
  256.                                     Printf("EOF record not found\n");
  257.                                 }
  258.                             }
  259.                             else
  260.                             {
  261.                                 if(end)
  262.                                 {
  263.                                     Printf("File does not contain any data\n");
  264.                                 }
  265.                                 else
  266.                                 {
  267.                                     Printf("N%s","ot an Intel Hex file\n");
  268.                                 }
  269.                             }
  270.                         }
  271.                     }
  272.                     FreeVec(indata);
  273.                 }
  274.                 else
  275.                 {
  276.                     Printf("Can't allocate memory for input file\n");
  277.                 }
  278.                 Close(infile);
  279.             }
  280.         }
  281.         else
  282.         {
  283.             Printf("Error in arguments\n");
  284.         }
  285.         CloseLibrary(DOSBase);
  286.     }
  287.     return(rc);
  288. }
  289.  
  290. UBYTE unhex(void)
  291. {
  292.     return((UBYTE)((unhexbyte()<<4)+unhexbyte()));
  293. }
  294.  
  295. UBYTE unhexbyte(void)
  296. {
  297.     if(*inpoint<='9')
  298.     {
  299.         return((UBYTE)((*inpoint++)-'0'));
  300.     }
  301.     return((UBYTE)(((*inpoint++)|32)-'a'+10));
  302. }
  303.